home *** CD-ROM | disk | FTP | other *** search
/ PC-Blue - MS DOS Public Domain Library / PC-Blue MS-DOS Public Domain Library - NYACC.iso / vol086 / roff47.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-12-15  |  8.4 KB  |  326 lines

  1. /********************************************************/
  2. /*                            */
  3. /*            ROFF4, Version 1.60            */
  4. /*                            */
  5. /*(C) 1983,4 by Ernest E. Bergmann            */
  6. /*        Physics, Building #16            */
  7. /*        Lehigh Univerisity            */
  8. /*        Bethlehem, Pa. 18015            */
  9. /*                            */
  10. /* Permission is hereby granted for all commercial and    */
  11. /* non-commercial reproduction and distribution of this    */
  12. /* material provided this notice is included.        */
  13. /*                            */
  14. /********************************************************/
  15. /*Feb 15, 1984*/
  16. /*January 9, 1984*/
  17. /********************************************************/
  18. /* March 1984  DeSmet C version */
  19. /* Henry Harpending*/
  20. /* Anthropology Department*/
  21. /* University of New Mexico*/
  22. /* Albuquerque, NM  87131*/
  23. /*   no restrictions */
  24. /*********************************************************/
  25. #include "a:roff4.h"
  26. /*assuming REVSCROLL is FALSE*/
  27. /*output OUTBUF2 whith the vertical height of the mainline
  28. specified by VLINENO,FVLINENO[they must not be changed here].
  29. Excessive superscripting will be pushed down.*/
  30.  
  31. printout()
  32. {int level,top,bot;    /*"up" is negative;units fractional*/
  33. int lsave,fsave;
  34.  
  35. OUTBUF2[BPOS]='\0';
  36. fsave=FVLINENO;
  37. lsave=VLINENO;
  38. level=FRVAL*(PLINENO-VLINENO)+FPLINENO-FVLINENO;
  39. if(!OLDBOT) level++;
  40. excurs(&OUTBUF2[0],&top,&bot);
  41. if(top>level) level=top;
  42.  
  43. if(!REVSCROLL) FVLINENO += level;
  44. padv();
  45. for(;level<=bot;level++)
  46.     {OCNT=0;
  47.     do {OCNT++; flp(level,FALSE); }
  48.     while(retype());
  49.     if(level<bot)
  50.         {fraction();
  51.         cputc('\n',ofp);
  52.         FPLINENO++;
  53.         }
  54.     }
  55. flp(level,TRUE);    /*update UF, XF, MCNT*/
  56. OUTBUF2[0]=BPOS=0;
  57. OLDLN=VLINENO=lsave;
  58. OLDBOT=bot;
  59. FVLINENO=fsave;
  60. }
  61. /****************************************/
  62. /*moves printer vertically so that its position is specified
  63. by VLINENO,FVLINENO*/
  64. padv()
  65. {int w,f;    /*whole,fractional lines*/
  66. w=VLINENO-PLINENO;
  67. f=FVLINENO-FPLINENO;
  68. while(f<0) {w--; f += FRVAL; }
  69. while(f>=FRVAL)    {w++; f -= FRVAL; }
  70. if(w<0){fprintf(stderr,"padv():VL=%d,PL=%d\n",
  71.             VLINENO,PLINENO);
  72.     if(REVSCROLL) backup(w*FRVAL+f);
  73.     else {VLINENO +=w;
  74.           FVLINENO +=f;
  75.           while(FVLINENO<0){VLINENO++;FVLINENO+=FRVAL;}
  76.           while(FVLINENO<FRVAL){VLINENO--;FVLINENO-=FRVAL;}
  77.           return;
  78.          }
  79.     }
  80. if(FRQ)    {while(f--){cputc('\n',ofp); FPLINENO++; }
  81.     if(w){whole();while(w--){cputc('\n',ofp);PLINENO++;}}
  82.     }
  83. else    {while(w--){cputc('\n',ofp); PLINENO++; }
  84.     if(f){fraction();while(f--){cputc('\n',ofp);FPLINENO++;}}
  85.     }
  86. while(FPLINENO>=FRVAL) {PLINENO++; FPLINENO -= FRVAL; }
  87. }
  88. /****************************************/
  89. backup(i)    /*not yet implemented*/
  90. int i;        /*# of fractional lines(probably negative)*/
  91. {fprintf(stderr,"\nCan't back up yet\n");
  92. }
  93. /**************************************************/
  94. excurs(str,t,b) /*finds the topmost and bottommost line
  95.         positions of str*/
  96. char *str;
  97. int *t,*b;
  98. {int l;
  99. char c;
  100. *t=*b=l=0; /*current line position */
  101. c=*str;
  102. while(c){if(c==CFVAL){if(c=*(++str))
  103.             switch(c)
  104.             {case '+':l--; if(l<*t) *t=l;
  105.                 c=*(++str); break;
  106.             case '-':l++; if(l>*b) *b=l;
  107.                 c=*(++str); break;
  108.             default : c=*(++str); break;
  109.             }
  110.             }
  111.     else c=*(++str);
  112.     }
  113. }
  114.  
  115. /**************************************************/
  116. flp(level,updat)/*fancy line print at a given vertical level
  117.         the string in OUTBUF2[] with backspacing,
  118.         underlining, and strikout.  To permit boldface
  119.         it modifies DBUF[],DPOS so that retype can be
  120.         used to patch up OUTBUF2 for resubmittal to
  121.         flp()*/
  122. int level;    /* current vertical level to print*/
  123. int updat;    /* boolean for update of UF,XF,MCNT*/
  124. {int i;
  125.     BLKCNT=lbc(level,OUTBUF2);
  126.     FIRST=TRUE;
  127.     while((BLKCNT>0)||updat)
  128.         {prpass(level,updat); cputc('\r',ofp);
  129.         updat=FIRST=FALSE;
  130.         }
  131.     if(XCOL>-1){for(i=0;i<=XCOL;i++)
  132.             cputc(XBUF[i],ofp);
  133.             cputc('\r',ofp);
  134.            }
  135.     if(UCOL>-1){for(i=0;i<=UCOL;i++)
  136.             cputc(UBUF[i],ofp);
  137.             cputc('\r',ofp);
  138.            }
  139.     if((UCOL>-1)||(XCOL>-1)) initxu();
  140. }
  141.  
  142. /**************************************************/
  143. retype()    /*restores characters into OUTBUF2 from DBUF
  144.         that need to be overstruck again*/
  145. {int i;
  146. if(DPOS==-1) return(FALSE);
  147. else    {for(i=0;i<=DPOS;i++)
  148.         {if(DBUF[i])
  149.             {OUTBUF2[i]=DBUF[i];
  150.             DBUF[i]=FALSE;
  151.             }
  152.         }
  153.     DPOS=-1;
  154.     return(TRUE);
  155.     }
  156. }
  157.  
  158. /**************************************************/
  159. int lbc(lev,str) /*counts printable chars in line level and
  160.         above; parity must be reset*/
  161. int lev; /*=0 main line,=-1 superscripts,=+1 subscripts, etc.*/
  162. char *str;
  163. {char c,n;
  164. int l;
  165. l=n=0;
  166. c=*str;
  167. while(c){if(c==CFVAL){if(c=*(++str))
  168.             switch(c)
  169.             {case '+':l--;c=*(++str);break;
  170.             case '-':l++;c=*(++str);break;
  171.             default: c=*(++str);break;
  172.             }    }
  173.     else    {if((c>' ')&&(l<=lev)) if(c!=TCVAL) n++;
  174.         c=*(++str);
  175.         }
  176.     }
  177. return(n);
  178. }
  179.  
  180. /**************************************************/
  181. prpass(lev,updat) /*printer pass initial cr; no lf anywhere*/
  182. int lev; /*=0 main line,=-1 superscripts,=+1 subscripts, etc.*/
  183. int updat;/*boolean to update UF,XF,MCNT*/
  184. {char ch;
  185. int l;
  186. int xfs,ufs,mcnts;    /*save variables*/
  187. int p1,p2,p3;        /*position holders*/
  188. int cp2;    /*for tabulation calculation*/
  189. xfs=XF; ufs=UF; mcnts=MCNT;
  190. p1=p2=p3=l=BPOS=CP=PP=0;
  191. while(ch=OUTBUF2[BPOS])
  192.     {switch (class(ch))
  193.     {case    BLACK:/*print it if posssible*/
  194.         if((PP>CP)||(l>lev)){CP++;BPOS++;break;}
  195.         else    {while(CP>PP){cputc(' ',ofp);PP++;}
  196.             if(ch==SCVAL)cputc(' ',ofp);
  197.             else cputc(ch,ofp);PP++;
  198.             if(MCNT>OCNT)
  199.                 {DBUF[BPOS]=OUTBUF2[BPOS];
  200.                 if(BPOS>DPOS) DPOS=BPOS;
  201.                 }
  202.             OUTBUF2[BPOS++]=' ';
  203.             if(UF&&FIRST)UBUF[UCOL=CP]=UCHAR;
  204.             if(XF&&FIRST)XBUF[XCOL=CP]=XCHAR;
  205.             BLKCNT--; CP++;
  206.             } break;
  207.     case    WHITE:/*assume blank*/ CP++;BPOS++;break;
  208.     case    TRANSLATE:/*similar to BLACK and WHITE*/
  209.             ch=OUTBUF2[++BPOS];
  210.             if((PP>CP)||(l>lev)||(ch==' '))
  211.                 {CP++;BPOS++;break;}
  212.             else
  213.               {while(CP>PP){cputc(' ',ofp);PP++;}
  214.             trch(ch);PP++;
  215.             if(MCNT>OCNT)
  216.                 {DBUF[BPOS]=OUTBUF2[BPOS];
  217.                 DBUF[BPOS-1]=OUTBUF2[BPOS-1];
  218.                 if(BPOS>DPOS) DPOS=BPOS;
  219.                 }
  220.             OUTBUF2[BPOS++]=' ';
  221.             if(UF&&FIRST)UBUF[UCOL=CP]=UCHAR;
  222.             if(XF&&FIRST)XBUF[XCOL=CP]=XCHAR;
  223.             BLKCNT--; CP++;
  224.             } break;
  225.     case    CONTROL:/*decode on following letter*/
  226.             ch=OUTBUF2[++BPOS];
  227.             if(CPTR[ch-' ']) pcont(ch);
  228.             else switch(ch)
  229.             {case 'h':
  230.             case 'H':/*backspace*/
  231.                 if(CP)CP--;break;
  232.             case '+': l--; break;
  233.             case '-': l++; break;
  234.             case 'U': UF=TRUE;break;
  235.             case 'u': UF=FALSE;break;
  236.             case 'X': XF=TRUE;break;
  237.             case 'x': XF=FALSE;break;
  238.             case 'B': MCNT *=3;break;
  239.             case 'b': if(!(MCNT /=3))MCNT=1;
  240.                     break;
  241.             case 'D': MCNT *=2;break;
  242.             case 'd': if(!(MCNT /=2))MCNT=1;
  243.                     break;
  244.             case '(': p1=CP;break;
  245.             case ')': CP=p1;break;
  246.             case '[': p2=CP;break;
  247.             case ']': CP=p2;break;
  248.             case '{': p3=CP;break;
  249.             case '}': CP=p3;break;
  250.             default:/*?,ignore*/;break;
  251.             } BPOS++; break;
  252.     case    SENTINEL: OUTBUF2[BPOS]=0;break;
  253.     case    HTAB: for(cp2=0;CP>=0;cp2+=TABSIZ)CP-=TABSIZ;
  254.             CP=cp2; BPOS++; break;
  255.     case    OTHERS:
  256.        fprintf(stderr,"\nweird character value: %o\n",ch);
  257.         BPOS++;
  258.         break;
  259.     }}
  260. if(!updat){/*restore original values*/
  261.     XF=xfs;
  262.     UF=ufs;
  263.     MCNT=mcnts;
  264.     }
  265. }
  266. /**************************************************/
  267. int class(c)
  268. char c;
  269. {if(c==TCVAL) return(TRANSLATE);
  270. if (c==CFVAL) return(CONTROL);
  271. if(c>' ') return(BLACK);
  272. if(c==' ') return(WHITE);
  273. if(c=='\n') return(SENTINEL);
  274. if(c=='\r') return(SENTINEL);
  275. if(c==TAB) return(HTAB);
  276. if(!c) return(SENTINEL);
  277. return(OTHERS);
  278. }
  279. /**************************************************/
  280. fraction()    /*put printer in fractional spcing mode;
  281.             set FRQ*/
  282. {if(!FRQ && FRSTRING && (FRVAL!=1))
  283.     {outstr(FRSTRING);
  284.     FRQ = TRUE;
  285.     }
  286. }
  287. /**************************************************/
  288. whole()        /*put printer in whole line spacing;
  289.             reset FRQ */
  290. {if(FRQ && WHSTRING)
  291.     {outstr(WHSTRING);
  292.     FRQ = FALSE;
  293.     }
  294. }
  295. /**************************************************/
  296. trch(c)    /*output string translation of c*/
  297. char c;
  298. {char *p;
  299.     if(c<' ') {cputc(TCVAL,ofp);cputc(c);return;}
  300.     p = TPTR[c-' '];
  301.     if(p) outstr(p);
  302.     else    {/*not initialized*/
  303.         cputc(TCVAL,ofp);
  304.         cputc('?',ofp);
  305.         }
  306. }
  307. /****************************************/
  308. pcont(c) /*output printer control string for c*/
  309. char c;
  310. {char *p;
  311.     if(c<' ') {cputc(CFVAL,ofp);cputc(c,ofp);return;}
  312.     p = CPTR[c-' '];
  313.     if(p) outstr(p);
  314.     else    {/*not initialized*/
  315.         cputc(CFVAL,ofp);
  316.         cputc('?',ofp);
  317.         }
  318. }
  319. /********************************************************/
  320. cputc(c,fp)
  321.     char c;
  322.     FILE fp;
  323. {
  324.     if (! SUPPRESS) putc(c,fp);
  325. }
  326.